#!/usr/bin/python

# Copyright (c) 2007 Matt Giger http://www.earthbrowser.com
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.


import os
import sys
from boto.s3.key import Key
from boto.connection import S3Connection
from boto.exception import S3ResponseError

##
## Warning: You must set these to your Amazon access and secret keys
## in order for this script to work
##

#_aws_access_key = 'XXXXX'
#_aws_secret_key = 'XXXXX'

##
## Print usage statement
def usage():
	print 's3cmd.py [command [args...]]'
	print '  buckets                      -list all buckets'
	print '  bcreate  bname                -create a bucket'
	print '  bdelete  bname                -delete a bucket'
	print '  objects  bname                -list all objects in named bucket'
	print '  odelete  bname oname          -delete an object from a bucket'
	print '  upload   bname oname fpath    -create a named object in bucket from fpath'
	print '  download bname oname fpath    -download an object from a bucket into fpath'
	print '  public   bname oname          -set access control to publicly readable'
	print '  private  bname oname          -set access control to private'

##
## Print the list of buckets
def list_buckets():
	c = S3Connection()
	buckets = c.get_all_buckets()
	for b in buckets:
		print b.name
	
##
## @param bname		Name of bucket
##
## Create a new bucket
def create_bucket(bname):
	c = S3Connection()
	bucket = c.create_bucket(bname)
	
##
## @param bname		Name of bucket
##
## Delete a bucket
def delete_bucket(bname):
	c = S3Connection()
	c.delete_bucket(bname)

##
## @param bname		Name of bucket
##
## Print the list of object keys in bucket
def list_objects(bname):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	for k in bucket.get_all_keys():
		print k.key
		
##
## @param bname		Name of bucket
## @param oname		Name of object
##
## Delete an object from a bucket
def delete_object(bname, oname):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	bucket.delete_key(oname)

##
## @param bname		Name of bucket
## @param oname		Name of object
## @param fpath		Path to file source of object data
##
## Upload a file to the specified bucket
def upload_file(bname, oname, fpath):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	k = Key(bucket)
	k.key = oname
	k.set_contents_from_filename(fpath)
	
##
## @param bname		Name of bucket
## @param oname		Name of object
## @param fpath		Path to file destination of object data
##
## Download a file from the specified object
def download_file(bname, oname, fpath):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	k = Key(bucket)
	k.key = oname
	k.get_contents_to_filename(fpath)

##
## @param bname		Name of bucket
## @param oname		Name of object
##
## Set access control to public-read
def set_access_public(bname, oname):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	k = bucket.lookup(oname)
	if k:
		k.set_acl('public-read')
	else:
		print 'error: %s:%s not found' % (bname, oname)

##
## @param bname		Name of bucket
## @param oname		Name of object
##
## Set access control to private
def set_access_private(bname, oname):
	c = S3Connection()
	bucket = c.get_bucket(bname)
	k = bucket.lookup(oname)
	if k:
		k.set_acl('private')
	else:
		print 'error: %s:%s not found' % (bname, oname)

##
## Main program interface
def main():

	if(len(sys.argv) < 2):
		usage()
		sys.exit(2)
	
	try:
		os.environ['AWS_ACCESS_KEY_ID'] = _aws_access_key
		os.environ['AWS_SECRET_ACCESS_KEY'] = _aws_secret_key

		if sys.argv[1] == 'buckets':
			list_buckets()
			
		elif sys.argv[1] == 'bcreate' and len(sys.argv) > 2:
			create_bucket(sys.argv[2])
			
		elif sys.argv[1] == 'bdelete' and len(sys.argv) > 2:
			delete_bucket(sys.argv[2])
			
		elif sys.argv[1] == 'objects' and len(sys.argv) > 2:
			list_objects(sys.argv[2])
		
		elif sys.argv[1] == 'odelete' and len(sys.argv) > 3:
			delete_object(sys.argv[2], sys.argv[3])
		
		elif sys.argv[1] == 'upload' and len(sys.argv) > 4:
			upload_file(sys.argv[2], sys.argv[3], sys.argv[4])
		
		elif sys.argv[1] == 'download' and len(sys.argv) > 4:
			download_file(sys.argv[2], sys.argv[3], sys.argv[4])
		
		elif sys.argv[1] == 'public' and len(sys.argv) > 3:
			set_access_public(sys.argv[2], sys.argv[3])
		
		elif sys.argv[1] == 'private' and len(sys.argv) > 3:
			set_access_private(sys.argv[2], sys.argv[3])
			
		else:
			usage()
			sys.exit(2)
			
	except S3ResponseError, e:
		print e
		sys.exit(1)
			
		
##
## Can (and should) be run from the command line		
if __name__ == '__main__':
	main()

